Import Necessary Modules¶

In [1]:
from pathlib import Path

from ipyniivue import download_dataset

BASE_API_URL = "https://niivue.com/demos/images/"
DATA_FOLDER = Path("images")

# Download data for example
download_dataset(
    BASE_API_URL,
    dest_folder=DATA_FOLDER,
    files=[
        "mni152.nii.gz",
        "aal.nii.gz",
        "aal.json",
    ],
)
mni152.nii.gz already exists.
aal.nii.gz already exists.
aal.json already exists.
Dataset downloaded successfully to images.
In [2]:
import json

import ipywidgets as widgets
from IPython.display import display

from ipyniivue import NiiVue, ShowRender

# Create NiiVue Instance

nv = NiiVue(
    show_3d_crosshair=True,
    back_color=(0.5, 0.5, 0.5, 1),
)

nv.set_interpolation(True)
nv.opts.crosshair_gap = 12
nv.opts.multiplanar_show_render = ShowRender.ALWAYS
nv.opts.drag_mode = "PAN"
nv.opts.yoke_3d_to_2d_zoom = True

nv.load_volumes(
    [
        {"path": DATA_FOLDER / "mni152.nii.gz"},
        {"path": DATA_FOLDER / "aal.nii.gz"},
    ]
)

# Load colormap label

with open(DATA_FOLDER / "aal.json") as f:
    cmap = json.load(f)

nv.volumes[1].set_colormap_label(cmap)

clut = nv.volumes[1].colormap_label.lut.copy()

# Make all regions translucent by setting alpha values to 96
for i in range(3, len(clut), 4):
    clut[i] = 96

# Update the colormap label with the modified lut
nv.volumes[1].colormap_label.lut = clut

# Add other widgets

interp_checkbox = widgets.Checkbox(
    value=True,
    description="Jagged",
)

outline_slider = widgets.IntSlider(
    min=0,
    max=255,
    value=1,
    description="Outline",
)

alpha_slider = widgets.IntSlider(
    min=1,
    max=255,
    value=150,
    description="Opacity",
)

pad_slider = widgets.IntSlider(
    min=0,
    max=10,
    value=5,
    description="Padding",
)

gap_slider = widgets.IntSlider(
    min=0,
    max=36,
    value=12,
    description="Crosshair Gap",
)

# Setup observer functions


def on_outline_change(change):
    """Handle changes in the outline slider."""
    nv.set_atlas_outline(change["new"] / 255)


def on_alpha_change(change):
    """Handle changes in the opacity slider."""
    nv.volumes[1].opacity = change["new"] / 255


def on_pad_change(change):
    """Handle changes in the padding slider."""
    nv.opts.multiplanar_pad_pixels = change["new"]


def on_gap_change(change):
    """Handle changes in the crosshair gap slider."""
    nv.opts.crosshair_gap = change["new"]


def on_interp_change(change):
    """Handle changes in the interpolation checkbox."""
    nv.set_interpolation(change["new"])


# Observe changes

# Observe changes in widget values and call the respective functions
outline_slider.observe(on_outline_change, names="value")
alpha_slider.observe(on_alpha_change, names="value")
pad_slider.observe(on_pad_change, names="value")
gap_slider.observe(on_gap_change, names="value")
interp_checkbox.observe(on_interp_change, names="value")

# Initialize the NiiVue instance with the current widget values
on_alpha_change({"new": alpha_slider.value})
on_outline_change({"new": outline_slider.value})
nv.opts.multiplanar_pad_pixels = pad_slider.value
nv.opts.crosshair_gap = gap_slider.value
nv.set_interpolation(interp_checkbox.value)

# Setup hover and click updates

output = widgets.HTML("Hover:<br>Clicked:")

active_idx = -1


@nv.on_hover_idx_change
def on_hover_idx_change(data):
    """Handle hover updates."""
    global active_idx
    idx_values = data["idxValues"]
    idx = idx_values[1]["idx"]
    if idx is not None and idx != active_idx:
        nv.opts.atlas_active_index = idx
        label = cmap["labels"][idx] if idx < len(cmap["labels"]) else ""
        clicked_line = output.value.split("Clicked:")[1]
        output.value = f"Hover: {label}<br>Clicked:{clicked_line}"


@nv.on_location_change
def handle_location_change(location):
    """Handle mouse clicks."""
    hover_line = output.value.split("Hover:")[1].split("<br>")[0]
    output.value = f"Hover:{hover_line}<br>Clicked: {location['string']}"


# Display all

controls = widgets.VBox(
    [
        interp_checkbox,
        outline_slider,
        alpha_slider,
        pad_slider,
        gap_slider,
        output,
    ]
)

display(
    widgets.VBox(
        [
            controls,
            nv,
        ]
    )
)